#include "zy_light_sensor.h"
#include "adi1787.h"
#include "ps.h"

#include "headset_sm.h"
#include "headset_test.h"
#include "ui_inputs.h"
#include "ui.h"
#include "zy_i2c.h"
#include "adk_log.h"

#define light_sensor_enabled_init 1
LightSensorTaskData light_sensor_tast;
uint8 wear_state = 1;
uint8 anc_state_tmp;
uint8 music_paused_by_light = 0;
uint32 wearless_time = 0;
static Task hs_task;

static void Light_Sensor_Detect_handler(Task task, MessageId id, Message msg)
{
    UNUSED(task);
    UNUSED(msg);
    switch (id)
    {
    case EventLSDetectOFFLED:
        DEBUG_LOG_V_VERBOSE("EventLSDetectOFFLED!!!\n");
        Light_Sensor_Detect_OFFLED();
        break;
    case EventLSDetectONLED:
        DEBUG_LOG_V_VERBOSE("EventLSDetectONLED!!!\n");
        Light_Sensor_Detect_ONLED();
        break;
    case EventLSDetectOFFLEDRecheck:
        DEBUG_LOG_V_VERBOSE("EventLSDetectOFFLEDRecheck!!!\n");
        Light_Sensor_Detect_OFFLED_Recheck();
        break;
    case EventLSMusicPause:
        Ui_InjectUiInput(ui_input_pause);
        break;
    case EventLSMusicPlay:
        Ui_InjectUiInput(ui_input_play);
        break;
#if WEAR_DETECT_USE_STK33532
    case EventSTK33532Start:
        STK33532_Wear_Detect();
        MessageCancelAll(LightSensorGetTask(), EventSTK33532Start);
        MessageSendLater(LightSensorGetTask(), EventSTK33532Start, 0, 500);
        break;
#endif
    default:
        break;
    }
}

/* 灭灯检查 */
void Light_Sensor_Detect_OFFLED(void)
{
#if WEAR_DETECT_USE_HY
    MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLED);
    if ((PioGet32Bank(0) & WEAR_RESULT_PIN)) // 未佩戴
    {
        if (wear_state) // 判断是否有佩戴变化
        {
            No_Wear_State_Operate();
        }
        else
        {
            wearless_time++;
            if (wearless_time > 600) // 未佩戴时长超过10分钟,执行关机
            {
                wearless_time = 0;
                Ui_InjectUiInput(ui_input_sm_power_off);
            }
        }
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 1000);
    }
    else
    {
        /* result pin低，佩戴状态不确定，启动1ms后开灯检测 */
        PioSetDir32Bank(0, WEAR_DETECT_PIN, WEAR_DETECT_PIN); // 设置GPIO输出模式
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);                  // 拉低GPIO
        MessageSendLater(LightSensorGetTask(), EventLSDetectONLED, 0, 1);
    }
#endif
}

/* 亮灯检查 */
void Light_Sensor_Detect_ONLED(void) // EventLSDetectONLED
{
#if WEAR_DETECT_USE_HY
    if ((PioGet32Bank(0) & WEAR_RESULT_PIN)) // 检测到佩戴
    {
        /* 重置佩戴传感器，5ms后重新灭灯检查 */
        PioSetDir32Bank(0, WEAR_DETECT_PIN, 0);
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);
        PioSetStrongBias32Bank(0, WEAR_DETECT_PIN, 0);
        MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLEDRecheck);
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLEDRecheck, 0, 5);
    }
    else // 检测到未佩戴
    {
        if (wear_state) // 判断是否有佩戴变化
        {
            No_Wear_State_Operate();
        }
        else
        {
            wearless_time++;
            if (wearless_time > 600) // 未佩戴时长超过10分钟,执行关机
            {
                Ui_InjectUiInput(ui_input_sm_power_off);
            }
        }
        /* 重置佩戴传感器，1s后开启下一轮检测 */
        PioSetDir32Bank(0, WEAR_DETECT_PIN, 0);
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);
        PioSetStrongBias32Bank(0, WEAR_DETECT_PIN, 0);
        MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 1000);
    }
#endif
}

/* 亮灯检测佩戴后，重复灭灯检查 */
void Light_Sensor_Detect_OFFLED_Recheck(void)
{
#if WEAR_DETECT_USE_HY
    if ((PioGet32Bank(0) & WEAR_RESULT_PIN)) // pin高，佩戴重复验证失败
    {
        if (wear_state) // 判断是否有佩戴变化
        {
            No_Wear_State_Operate();
        }
        else
        {
            wearless_time++;
            if (wearless_time > 600) // 未佩戴时长超过10分钟,执行关机
            {
                Ui_InjectUiInput(ui_input_sm_power_off);
            }
        }
    }
    else // pin低，确认佩戴
    {
        if (!wear_state) // 判断是否有佩戴变化
        {
            Wear_State_Operate();
        }
        wearless_time = 0;
    }
    MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
    MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 1000);
#endif
}

/* 执行佩戴状态切换 */
void Wear_State_Operate(void)
{
    uint8 response[3] = {0x0b, 0x0a, 0x00}; /* GAIA发送ANC实时状态 0：OFF,1：ON, 2：ambient sound */
    if (music_paused_by_light)
    {
        music_paused_by_light = 0;
        MessageCancelAll(LightSensorGetTask(), EventLSMusicPause);
        MessageSendLater(LightSensorGetTask(), EventLSMusicPlay, 0, 0);
    }
    /* ANC状态调整 */
    if ((anc_state == state_anc_off) && (anc_state_tmp != state_anc_off))
    {
        if (anc_is_changing)
        {
            /* 不进行操作 */
        }
        else
        {
            anc_is_changing = 1;
            wear_state = 1;
            if (anc_state_tmp == state_anc_on)
            {
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_DAC_POWER, 1, ADC_POWER_ON);   //ADC power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_MBIAS_PGA_POWER, 1, MBIAS_PGA_ON); //MBIAS PGA power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_MUTE_REG, 1, ADC_UNMUTE);      //ADC Unmuted
                if (anc_on_state == AncOnStateHigh)
                {
                    ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_BANK_CONTROL_REG, 1, BANK_A);      //BANK A
                }
                else
                {
                    ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_BANK_CONTROL_REG, 1, BANK_C);      //BANK C
                }
                MessageCancelAll(AncGetTask(), EventMyAncOnExeture);
                MessageSendLater(AncGetTask(), EventMyAncOnExeture, 0, 1000);
                response[2] = 1;
                if (anc_adaptive_enabled_temp)
                {
                    anc_adaptive_enabled_temp = 0;
                    MessageSendLater(AncAdaptiveGetTask(), EventAncAdaptiveStart, 0, 5000);
                }
            }
            else if (anc_state_tmp == state_monitor_on)
            {
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_DAC_POWER, 1, ADC_POWER_ON);   //ADC power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_MBIAS_PGA_POWER, 1, MBIAS_PGA_ON); //MBIAS PGA power on
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_ADC_MUTE_REG, 1, ADC_UNMUTE);      //ADC Unmuted
                ADI1787_Registers_write(i2c_addr_1787_8bit, ADI1787_BANK_CONTROL_REG, 1, BANK_B);      //BANK B
                MessageCancelAll(AncGetTask(), EventMyMonitorOnExeture);
                MessageSendLater(AncGetTask(), EventMyMonitorOnExeture, 0, 1000);
                response[2] = 2;
            }
            else
            {
                anc_is_changing = 0;
            }
            if (appDeviceIsHandsetConnected())
            {
                GaiaSendPacket(gaia_get_transport(), GAIA_VENDOR_QTIL, GAIA_EVENT_NOTIFICATION, GAIA_STATUS_NONE, 3, response);
            }
        }
    }
    else
    {
        wear_state = 1;
    }
}

/* 执行未佩戴状态切换 */
void No_Wear_State_Operate(void)
{
    uint8 response[3] = {0x0b, 0x0a, 0x00}; /* GAIA发送ANC实时状态 0：OFF,1：ON, 2：ambient sound */
    if (!anc_is_changing)
    {
        if (headset_sm.state == HEADSET_STATE_BUSY)
        {
            music_paused_by_light = 1;
            MessageCancelAll(LightSensorGetTask(), EventLSMusicPlay);
            MessageSendLater(LightSensorGetTask(), EventLSMusicPause, 0, 0);
        }
        anc_state_tmp = anc_state;
        if (anc_state != state_anc_off)
        {
            anc_is_changing = 1;
            if (anc_state == state_anc_on)
            {
                anc_adaptive_enabled_temp = anc_adaptive_enabled_temp | anc_adaptive_enabled;
                if (anc_adaptive_enabled)
                {
                    MessageSend(AncAdaptiveGetTask(), EventAncAdaptiveStop, 0);
                }
            }
            Enter_IIS_Only();
        }
        wear_state = 0;
        GaiaSendPacket(gaia_get_transport(), GAIA_VENDOR_QTIL, GAIA_EVENT_NOTIFICATION, GAIA_STATUS_NONE, 3, response);
    }
    else
    {
        /* 等待上一个ANC状态调整完成 */
    }
}

#if WEAR_DETECT_USE_STK33532
void STK33532_Reg_Init(void)
{
    uint8_t val = 0;
    i2c_read_byte(STK33532_I2C_ADDR, 0x3e, &val, 1);
    if (val == 0x51)
    {
        i2c_write_byte(STK33532_I2C_ADDR, 0x0, 0);
        i2c_write_byte(STK33532_I2C_ADDR, 0x01, 0x31);
        i2c_write_byte(STK33532_I2C_ADDR, 0x02, 0x22);
        i2c_write_byte(STK33532_I2C_ADDR, 0x03, 0x60);
        i2c_write_byte(STK33532_I2C_ADDR, 0x04, 0x00);
        i2c_write_byte(STK33532_I2C_ADDR, 0x05, 0xff);
        i2c_write_byte(STK33532_I2C_ADDR, 0x4e, 0x20);
        i2c_write_byte(STK33532_I2C_ADDR, 0xa0, 0x10);
        i2c_write_byte(STK33532_I2C_ADDR, 0xdb, 0x01);
        i2c_write_byte(STK33532_I2C_ADDR, 0xa1, 0x7c);
        i2c_write_byte(STK33532_I2C_ADDR, 0xa8, 0xff);
        i2c_write_byte(STK33532_I2C_ADDR, 0xa9, 0xff);
        i2c_write_byte(STK33532_I2C_ADDR, 0xaa, 0x0c);
        i2c_write_byte(STK33532_I2C_ADDR, 0xf6, 0x82);
        i2c_write_byte(STK33532_I2C_ADDR, 0x6, 0x07);
        i2c_write_byte(STK33532_I2C_ADDR, 0x7, 0x00);
        i2c_write_byte(STK33532_I2C_ADDR, 0x8, 0x07);
        i2c_write_byte(STK33532_I2C_ADDR, 0x9, 0x08);
        i2c_write_byte(STK33532_I2C_ADDR, 0x0, 0x05);
        wearless_time = 0;
        wear_state = 1;
        MessageCancelAll(LightSensorGetTask(), EventSTK33532Start);
        MessageSendLater(LightSensorGetTask(), EventSTK33532Start, 0, 5000);
    }
    else
    {
        DEBUG_LOG_WARN("STK33532_Reg_Init error!!!");
    }
}

void STK33532_Wear_Detect(void)
{
    uint8_t val = 0;
    bool ret;
    ret = i2c_read_byte(STK33532_I2C_ADDR, 0x10, &val, 1);
    if (ret)
    {
        if (val & 0x01) // 未佩戴
        {
            DEBUG_LOG_VERBOSE("STK33532_Wear_Detect: no wear!");
            if (wear_state) // 判断是否有佩戴变化
            {
                wearless_time++;
                if (wearless_time > 2) /* 超过3次检测未佩戴，执行待机操作 */
                {
                    wearless_time = 0;
                    No_Wear_State_Operate();
                }
            }
        }
        else
        {
            DEBUG_LOG_VERBOSE("STK33532_Wear_Detect: wear!");
            if (!wear_state) // 判断是否有佩戴变化
            {
                Wear_State_Operate();
            }
            wearless_time = 0;
        }
    }
    else
    {
        DEBUG_LOG_VERBOSE("STK33532_Wear_Detect: sensor state error!");
    }
}
#endif

void Light_Sensor_Init(Task init_task)
{
    uint16 ret_len;
    uint16 requested_words;
    uint16 light_sensor_endabled;
    LightSensorTaskData *theuser = LightSensorGetTaskData();
    requested_words = PS_SIZE_ADJ(sizeof(uint16));
    ret_len = PsRetrieve(light_sensor_enabled_key, NULL, 0);
    if (!ret_len) /* 系统第一次上电，默认开启佩戴传感器并保存pskey */
    {
        light_sensor_endabled = light_sensor_enabled_init;
        PsStore(light_sensor_enabled_key, (const uint16 *)&light_sensor_endabled, requested_words);
    }
    else
    {
        PsRetrieve(light_sensor_enabled_key, &light_sensor_endabled, requested_words);
    }
    if (light_sensor_endabled)
    {
        /* 初始化任务 */
        hs_task = init_task;
        memset(theuser, 0, sizeof(*theuser));
        theuser->task.handler = Light_Sensor_Detect_handler;
        music_paused_by_light = 0;
#if WEAR_DETECT_USE_HY
        /* 重置佩戴传感器，1s后开启下一轮检测 */
        PioSetMapPins32Bank(0, WEAR_DETECT_PIN, WEAR_DETECT_PIN);
        PioSetDir32Bank(0, WEAR_DETECT_PIN, 0);
        PioSet32Bank(0, WEAR_DETECT_PIN, 0);
        PioSetStrongBias32Bank(0, WEAR_DETECT_PIN, 0);

        PioSetMapPins32Bank(0, WEAR_RESULT_PIN, WEAR_RESULT_PIN);
        PioSetDir32Bank(0, WEAR_RESULT_PIN, 0);        // 设置GPIO4输入模式
        PioSet32Bank(0, WEAR_RESULT_PIN, 0);           // 设置下拉
        PioSetStrongBias32Bank(0, WEAR_RESULT_PIN, 0); // 设置高阻

        /* 开机10秒后启动光感检测，1s检测一次*/
        wearless_time = 0;
        wear_state = 1;
        MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLED);
        MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
        MessageSendLater(LightSensorGetTask(), EventLSDetectOFFLED, 0, 10000);
#elif WEAR_DETECT_USE_STK33532
        STK33532_Reg_Init();
#endif
    }
}

void Light_Sensor_DeInit(void)
{
#if WEAR_DETECT_USE_HY
    MessageCancelAll(LightSensorGetTask(), EventLSDetectOFFLED);
    MessageCancelAll(LightSensorGetTask(), EventLSDetectONLED);
    PioSetDir32Bank(0, WEAR_RESULT_PIN | WEAR_DETECT_PIN, 0);        // 设置GPIO5输入模式
    PioSet32Bank(0, WEAR_RESULT_PIN | WEAR_DETECT_PIN, 0);           // 设置下拉
    PioSetStrongBias32Bank(0, WEAR_RESULT_PIN | WEAR_DETECT_PIN, 0); // 设置高阻
#elif WEAR_DETECT_USE_STK33532
    i2c_write_byte(STK33532_I2C_ADDR, 0x0, 0);
    MessageCancelAll(LightSensorGetTask(), EventSTK33532Start);
#endif
}
/* adi1787库控制佩戴传感器回调函数 */
void set_light_sensor_enabled(bool mode)
{
    uint16 light_sensor_endabled;
    uint16 requested_words;
    requested_words = PS_SIZE_ADJ(sizeof(uint16));
    if (mode)
    {
        light_sensor_endabled = 1;
        PsStore(light_sensor_enabled_key, (const uint16 *)&light_sensor_endabled, requested_words);
        Light_Sensor_Init(hs_task);
    }
    else
    {
        light_sensor_endabled = 0;
        PsStore(light_sensor_enabled_key, (const uint16 *)&light_sensor_endabled, requested_words);
        Light_Sensor_DeInit();
    }
}

/* adi1787库控制佩戴传感器回调函数 */
bool get_light_sensor_enabled(void)
{
    uint16 requested_words, ret_len, ret;
    requested_words = PS_SIZE_ADJ(sizeof(uint16));
    ret_len = PsRetrieve(light_sensor_enabled_key, NULL, 0);
    if (ret_len)
    {
        PsRetrieve(light_sensor_enabled_key, &ret, requested_words);
        if (ret)
        {
            return TRUE;
        }
    }
    return FALSE;
}
